﻿/*
 * 由SharpDevelop创建。
 * 用户： Administrator
 * 日期: 2017/4/28 星期五
 * 时间: 17:47
 * 
 * 要改变这种模板请点击 工具|选项|代码编写|编辑标准头文件
 */
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.Threading;
using System.ComponentModel;

namespace ModbusServer_Client
{
	/// <summary>
	/// Description of MainForm.
	/// </summary>
	public partial class MainForm : Form
	{
		EasyModbus.ModbusServer modbusServer;
		private EasyModbus.ModbusClient modbusClient;
        private BackgroundWorker bgWorker;
		
		public MainForm()
		{

			InitializeComponent();	
			ReadConfig();
			bgWorker = new BackgroundWorker();
			bgWorker.WorkerSupportsCancellation = true;
			bgWorker.DoWork += new DoWorkEventHandler(bw_DoWork);
			bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_Completed);
			
			modbusClient = new EasyModbus.ModbusClient();

			modbusServer = new EasyModbus.ModbusServer();
			modbusServer.FunctionCode1Disabled = true;
			modbusServer.FunctionCode2Disabled = true;
			modbusServer.FunctionCode4Disabled = true;
			modbusServer.FunctionCode5Disabled = true;
			modbusServer.FunctionCode6Disabled = true;
			modbusServer.FunctionCode15Disabled = true;
			modbusServer.FunctionCode16Disabled = true;
			modbusServer.FunctionCode23Disabled = true;
			
            modbusServer.Listen();
            label_statusShow.Text="Server Listening (Port " + modbusServer.Port + ")";
  
            bgWorker.RunWorkerAsync(SetbwArgs());
			
		}
		
		void ReadConfig()
		{
			tb_IpAdress.Text= System.Configuration.ConfigurationManager.AppSettings["SourceIP"];
			tb_remotePort.Text =System.Configuration.ConfigurationManager.AppSettings["SourcePort"];
			tb_localPort.Text = System.Configuration.ConfigurationManager.AppSettings["LocalPort"];
			tb_Cycle.Text =System.Configuration.ConfigurationManager.AppSettings["CycleTime"];
			tb_holdAdress.Text = System.Configuration.ConfigurationManager.AppSettings["HoldingRegisterStart"];
			tb_holdLen.Text = System.Configuration.ConfigurationManager.AppSettings["HoldingRegisterQuantity"];
		}
		
		public string[] SetbwArgs()
		{
			string [] args =new string[3];
			args[0]=tb_Cycle.Text;
			args[1]=tb_holdAdress.Text;
			args[2]=tb_holdLen.Text;
			return args;
		}
		
		//后台取数据
		void bw_DoWork(object sender, DoWorkEventArgs e)
		{
			string [] args =(string[])e.Argument;
			int cycle = int.Parse(args[0]);
			int start = int.Parse(args[1]);
			int quantity = int.Parse(args[2]);

			while (true)
			{		
				if(bgWorker.CancellationPending)
				{
					e.Cancel =true;
					break;
				}
				if(quantity>123)
				{
					int conout = quantity /123 ;
					int end = quantity % 123;
					for (int i = 0; i < conout; i++) {
						ReadHoldingRegisters(start+i*123,123);
					}
					ReadHoldingRegisters(start+conout*123,end);
				}else
				{
					ReadHoldingRegisters(start,quantity);
				}
				Thread.Sleep(cycle);
			}
					
		}
		
		void bw_Completed(object sender ,RunWorkerCompletedEventArgs e)
		{
			if (e.Cancelled)
			{
				bgWorker.RunWorkerAsync(SetbwArgs());
			}
		}
		
		//读取HoldingRegister
		void ReadHoldingRegisters(int start,int quantity)
		{
			 try
            {
                if (!modbusClient.Connected)
                {
                    modbusClient.IPAddress = tb_IpAdress.Text;
                    modbusClient.Port = int.Parse(tb_remotePort.Text);
                    modbusClient.Connect();
                }

               int[] serverResponse = modbusClient.ReadHoldingRegisters(start-1, quantity);
                
//               lb_Log.Items.Clear();
                for (int i = 0; i < serverResponse.Length; i++)
                {
//                	lb_Log.Items.Add(serverResponse[i]);
					modbusServer.holdingRegisters[start+i]=(short)serverResponse[i];
					                  
                }
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message, "Exception Reading values from Server", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
		
		}
		
		void Tb_TestClick(object sender, EventArgs e)
		{
			bgWorker.CancelAsync();
		}
		
		//重新配置
		void BtnReConfigClick(object sender, EventArgs e)
		{
			bgWorker.CancelAsync();
			modbusServer.StopListening();
			string p =tb_localPort.Text.ToString();			
			modbusServer.Port = Int32.Parse(p);
			modbusServer.UDPFlag = false;
            modbusServer.SerialFlag = false;
            modbusServer.PortChanged = true;
            modbusServer.Listen();	
            label_statusShow.Text="Server Listening (Port " + modbusServer.Port + ")";
		}


		//只能输入数字
		 void Tbx_number_KeyPress(object sender, KeyPressEventArgs e)  
		{  
            if (!Char.IsNumber(e.KeyChar) && !Char.IsPunctuation(e.KeyChar) && !Char.IsControl(e.KeyChar))  
            {  
                e.Handled = true;//消除不合适字符  
            }  
            else if (Char.IsPunctuation(e.KeyChar))  
            {  
                if (e.KeyChar != '.' || this.tb_IpAdress.Text.Length == 0)//小数点  
                {  
                    e.Handled = true;  
                }  
                if (tb_IpAdress.Text.LastIndexOf('.') != -1)  
                {  
                    e.Handled = true;  
                }  
            }        
  		}    
	}
}
